
#include "lib_mpp.h"

static MppBufferGroup  frm_grp;
static RK_U64          frame_err = 0;

int rkmpp_decoder_init(RKMPPCodecContext *mpp_ctx)
{
    MPP_RET ret = MPP_OK;
    MpiCmd mpi_cmd = MPP_CMD_BASE;
    MppParam param = NULL;
    RK_U32 need_split = 1;
	
	mpp_ctx->codectype = MPP_VIDEO_CodingAVC;

    ret = mpp_create(&mpp_ctx->ctx, &mpp_ctx->mpi);
    if (MPP_OK != ret) {
        log_e("mpi->control failed\n");
        return -1;
    }

    mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
    param = &need_split;
    ret = mpp_ctx->mpi->control(mpp_ctx->ctx, mpi_cmd, param);
    if (MPP_OK != ret) {
        log_e("mpi->control failed\n");
        return -1;
    }

    ret = mpp_init(mpp_ctx->ctx, MPP_CTX_DEC, mpp_ctx->codectype);
    if (MPP_OK != ret) {
        log_e("mpp_init failed\n");
        return -1;
    }

    return 0;
}

int decode_one_pkt(RKMPPCodecContext *mpp_ctx,uint8_t *data,int size,int pts)
{
    int ret;
    RK_U32 pkt_done = 0;
	MppPacket packet;
	MppFrame  frame = NULL;

	uint8_t * temp_data = NULL;

	RK_U32 width  = 0; 
	RK_U32 height = 0; 
	RK_U32 hor_stride  = 0; 
	RK_U32 ver_stride  = 0; 
	
	RK_S32 get_frm = 0;
	RK_U32 frm_eos = 0;
	
	RK_U32 show_once = 0;

	RK_S32 times = 3;

	long t1 = 0;
	long t2 = 0;

	if(!data)
		return -1;

	if(!size)
		return -1;

	temp_data = data;

    ret = mpp_packet_init(&packet, temp_data, size);
    if (MPP_OK != ret) {
        log_e("mpp_packet_init failed\n");
		return -1;
    }
	
    if (!(temp_data))
        mpp_packet_set_eos(packet);

    do {
        if (!pkt_done){
			ret = mpp_ctx->mpi->decode_put_packet(mpp_ctx->ctx, packet);
            if(MPP_OK == ret)
                pkt_done = 1;
        }

        do {
        try_again:
            ret = mpp_ctx->mpi->decode_get_frame(mpp_ctx->ctx, &frame);						
            if(MPP_ERR_TIMEOUT == ret) 
			{
                log_e("decode_get_frame failed too much time\n");

				if(times > 0){
                    times--;
                    msleep(MPP_H264_DECODE_TIMEOUT);
                    goto try_again;
                }
            }
			
            if(MPP_OK != ret){
                log_e("decode_get_frame failed ret %d\n", ret);
                break;
            }
			
            if(frame) {
                if(mpp_frame_get_info_change(frame)) {

					width      = mpp_frame_get_width(frame);
                    height     = mpp_frame_get_height(frame);
                    hor_stride = mpp_frame_get_hor_stride(frame);
                    ver_stride = mpp_frame_get_ver_stride(frame);

                    ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_DRM);
                    if (ret) {
                        log_e("get mpp buffer group  failed ret %d\n", ret);
                        break;
                    }
                    mpp_ctx->mpi->control(mpp_ctx->ctx, MPP_DEC_SET_EXT_BUF_GROUP, frm_grp);
                    mpp_ctx->mpi->control(mpp_ctx->ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
                } 
				else 
				{
					RK_U32 err_info = mpp_frame_get_errinfo(frame)|mpp_frame_get_discard(frame);

                    if(err_info) 
					{                       
					   frame_err++;
                    }
                    else 
                    {
						rkdrm_hdmi_display_video(frame);
						show_once = 0;
                    }
                }				
                frm_eos = mpp_frame_get_eos(frame);				
                mpp_frame_deinit(&frame);
                frame   = NULL;
                get_frm = 1;
            }
			else
			{
				get_frm = 0;
			}

            if(frm_eos)
                break;
			
			if(show_once)
				break;

            if(!get_frm)
                break;
        } while (1);

        if(pkt_done)
            break;

        msleep(MPP_H264_DECODE_TIMEOUT);
    } while (1);

	return 0;
}
